home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 2098 / 2098.xpi / components / unManager.js next >
Text File  |  2009-07-05  |  15KB  |  543 lines

  1. // Update Notifier
  2. // By Todd Long <longfocus@gmail.com>
  3. // http://www.longfocus.com/firefox/updatenotifier/
  4.  
  5. const UN_CC = Components.classes;
  6. const UN_CI = Components.interfaces;
  7. const UN_CS = UN_CC['@mozilla.org/consoleservice;1'].getService(UN_CI.nsIConsoleService);
  8.  
  9. const UN_BRANCH = "longfocus.updatenotifier.";
  10. const UN_BUNDLE = "chrome://updatenotifier/locale/updatenotifier.properties";
  11.  
  12. const UN_NOTIFY_TOPIC = "UN:update-topic";
  13. const UN_NOTIFY_TYPE_CHANGE = "UN:update-type-change";
  14. const UN_NOTIFY_TYPE_BUSY_NONE = "UN:update-type-busy-none";
  15. const UN_NOTIFY_TYPE_BUSY_CHECKING = "UN:update-type-busy-checking";
  16. const UN_NOTIFY_TYPE_BUSY_DOWNLOAD = "UN:update-type-busy-download";
  17. const UN_NOTIFY_TYPE_BUSY_INSTALL = "UN:update-type-busy-install";
  18.  
  19. const UN_ACTION_INSTALL = "UN:action-install";
  20. const UN_ACTION_REMOVE = "UN:action-remove";
  21. const UN_ACTION_UPDATE = "UN:action-update";
  22.  
  23. const nsIAddonInstallListener = Components.interfaces.nsIAddonInstallListener;
  24. const nsIAddonUpdateCheckListener = Components.interfaces.nsIAddonUpdateCheckListener;
  25. const nsIAddonUpdateListener = Components.interfaces.nsIAddonUpdateListener;
  26. const unIManager = Components.interfaces.unIManager;
  27. const nsIObserver = Components.interfaces.nsIObserver;
  28. const nsISupports = Components.interfaces.nsISupports;
  29.  
  30. function unManager() {}
  31. unManager.prototype = {
  32.   _items: new Array(),
  33.   _firstTime: true,
  34.   _theme: "classic/1.0",
  35.   _busyStatus: UN_NOTIFY_TYPE_BUSY_NONE,
  36.   _newUpdate: false,
  37.   
  38.   get branch()
  39.   {
  40.     return UN_CC["@mozilla.org/preferences-service;1"]
  41.              .getService(UN_CI.nsIPrefService)
  42.              .getBranch(UN_BRANCH);
  43.   },
  44.   
  45.   get bundle()
  46.   {
  47.     return UN_CC["@mozilla.org/intl/stringbundle;1"]
  48.              .getService(UN_CI.nsIStringBundleService)
  49.              .createBundle(UN_BUNDLE);
  50.   },
  51.   
  52.   get restart()
  53.   {
  54.     var restart = false;
  55.     
  56.     for (var id in this._items) {
  57.       if (this._items[id].needsRestart)
  58.         restart = true;
  59.     }
  60.     
  61.     return restart;
  62.   },
  63.   
  64.   get status()
  65.   {
  66.     return this._busyStatus;
  67.   },
  68.   
  69.   getItems: function(aCount)
  70.   {
  71.     var items = new Array();
  72.     
  73.     for (var id in this._items)
  74.       items.push(this._items[id]);
  75.     
  76.     aCount.value = items.length;       
  77.     
  78.     return items;
  79.   },
  80.   
  81.   getUpdateItems: function(aCount)
  82.   {
  83.     var items = new Array();
  84.     
  85.     for (var id in this._items) {
  86.       if (this._items[id].newVersion != null)
  87.         items.push(this._items[id]);
  88.     }
  89.     
  90.     aCount.value = items.length;       
  91.     
  92.     return items;
  93.   },
  94.   
  95.   load: function()
  96.   {
  97.     if (this._firstTime)
  98.     {
  99.       this._firstTime = false;
  100.       
  101.       this._em = UN_CC["@mozilla.org/extensions/manager;1"].getService(UN_CI.nsIExtensionManager);
  102.       this._observer = UN_CC["@mozilla.org/observer-service;1"].getService(UN_CI.nsIObserverService);
  103.       
  104.       // Adds observers for item updates
  105.       this._em.datasource.AddObserver(this);
  106.       
  107.       // Check for Toolkit 1.9 (Firefox 3)
  108.       if (typeof this._em.addInstallListener == "function")
  109.         this._em.addInstallListener(this);
  110.       else
  111.         this._em.addUpdateListener(this);
  112.       
  113.       try {
  114.         // Get theme in use
  115.         this._theme = UN_CC["@mozilla.org/preferences-service;1"].getService(UN_CI.nsIPrefBranch).getCharPref("general.skins.selectedSkin");
  116.       } catch(e) {}
  117.       
  118.       if (this.branch.getBoolPref("startup.check"))
  119.         this.checkUpdates();
  120.     }
  121.     
  122.     // Check RDF for available updates
  123.     var res = this._em.datasource.GetAllResources();
  124.     
  125.     while (res.hasMoreElements())
  126.     {
  127.       var element = res.getNext().QueryInterface(UN_CI.nsIRDFResource);
  128.       this._itemUpdateAction(this._em.datasource, element, UN_ACTION_UPDATE);
  129.     }
  130.     
  131.     if (this._newUpdate)
  132.       this._showAlert();
  133.   },
  134.   
  135.   checkUpdates: function()
  136.   {
  137.     var items = this._em.getItemList(UN_CI.nsIUpdateItem.TYPE_ANY, {});
  138.     this._em.update(items, items.length, false, this);
  139.   },
  140.   
  141.   installUpdates: function()
  142.   {
  143.     var itemList = new Array();
  144.     
  145.     for (var id in this._items)
  146.     {
  147.       // Make sure Firefox hasn't already installed
  148.       if (this._items[id].newVersion != null)
  149.         itemList.push(this._em.getItemForID(id));
  150.     }
  151.     
  152.     if (itemList.length > 0)
  153.     {
  154.       try {
  155.         this._em.addDownloads(itemList, itemList.length, true);
  156.       } catch(e) {
  157.         this._em.addDownloads(itemList, itemList.length, null);
  158.       }
  159.     }
  160.   },
  161.   
  162.   _itemUpdateAction: function(aDataSource, aSource, aAction, aOpType)
  163.   {
  164.     var arcLabelsOut = aDataSource.ArcLabelsOut(aSource);
  165.     var curItem = this._em.getItemForID(aSource.Value.replace("urn:mozilla:item:", ""));
  166.     var item = new unItem();
  167.     var internalName = null;
  168.     
  169.     // Check if the update item exists
  170.     if (curItem == null)
  171.       return;
  172.     
  173.     item.id = curItem.id;
  174.     item.name = curItem.name;
  175.     item.oldVersion = curItem.version;
  176.     item.newVersion = null;
  177.     item.updateInfo = "";
  178.     item.opType = aOpType;
  179.     item.needsRestart = true;
  180.     
  181.     switch (curItem.type)
  182.     {
  183.       case UN_CI.nsIUpdateItem.TYPE_EXTENSION:
  184.         item.type = "extension";
  185.         break;
  186.       case UN_CI.nsIUpdateItem.TYPE_THEME:
  187.         item.type = "theme";
  188.         break;
  189.       default: // Don't know, don't care
  190.         return;
  191.     }
  192.     
  193.     while (arcLabelsOut.hasMoreElements())
  194.     {
  195.       var labelOut = arcLabelsOut.getNext().QueryInterface(UN_CI.nsIRDFResource);
  196.       var target = aDataSource.GetTarget(aSource, labelOut, true);
  197.       var rdfLiteral = null;
  198.       
  199.       if (target instanceof UN_CI.nsIRDFLiteral)
  200.         rdfLiteral = target.Value;
  201.       
  202. //      UN_CS.logStringMessage("labelOut.Value - " + labelOut.Value);
  203. //      UN_CS.logStringMessage("rdfLiteral - " + rdfLiteral);
  204.       
  205.       if (labelOut.Value.indexOf("#availableUpdateVersion") > -1)
  206.         item.newVersion = rdfLiteral;
  207.       else if (labelOut.Value.indexOf("#internalName") > -1)
  208.         internalName = rdfLiteral;
  209.       else if (labelOut.Value.indexOf("#appDisabled") > -1 || labelOut.Value.indexOf("#userDisabled") > -1)
  210.         aAction = UN_ACTION_REMOVE;
  211.     }
  212.     
  213.     switch (aAction)
  214.     {
  215.       case UN_ACTION_UPDATE:
  216.       case UN_ACTION_INSTALL:
  217.       {
  218.         var isTheme = (item.type == "theme" && this._theme != internalName);
  219.         
  220.         if ((aAction == UN_ACTION_UPDATE || isTheme) && item.newVersion == null)
  221.           return;
  222.         
  223.         if (item.newVersion != null)
  224.           item.needsRestart = false;
  225.         
  226.         this._addItemUpdate(item);
  227.         break;
  228.       }
  229.       case UN_ACTION_REMOVE:
  230.       {
  231.         this._removeItemUpdate(item);
  232.         break;
  233.       }
  234.     }
  235.   },
  236.   
  237.   _addItemUpdate: function(aItem)
  238.   {
  239.     // Check if item exists
  240.     if (this._items[aItem.id])
  241.     {
  242.       // Check duplicate
  243.       if (this._items[aItem.id].id == aItem.id &&
  244.           this._items[aItem.id].name == aItem.name &&
  245.           this._items[aItem.id].oldVersion == aItem.oldVersion &&
  246.           this._items[aItem.id].newVersion == aItem.newVersion &&
  247.           this._items[aItem.id].opType == aItem.opType)
  248.         return;
  249.     }
  250.     
  251.     if (aItem.newVersion != null && this.branch.getBoolPref("alerts"))
  252.       this._newUpdate = true;
  253.     
  254.     // Add item
  255.     this._items[aItem.id] = aItem;
  256.     
  257.     // Notify change
  258.     this._observer.notifyObservers(null, UN_NOTIFY_TOPIC, UN_NOTIFY_TYPE_CHANGE);
  259.   },
  260.   
  261.   _removeItemUpdate: function(aItem)
  262.   {
  263.     // Check if item exists
  264.     if (this._items[aItem.id])
  265.     {
  266.       // Remove item
  267.       delete this._items[aItem.id];
  268.       
  269.       // Notify change
  270.       this._observer.notifyObservers(null, UN_NOTIFY_TOPIC, UN_NOTIFY_TYPE_CHANGE);
  271.     }
  272.   },
  273.   
  274.   _setBusyStatus: function(aStatus)
  275.   {
  276.     // Sets the status
  277.     this._busyStatus = aStatus;
  278.     
  279.     // Notifies the status
  280.     this._observer.notifyObservers(null, UN_NOTIFY_TOPIC, aStatus);
  281.   },
  282.   
  283.   _showAlert: function()
  284.   {
  285.     this._newUpdate = false;
  286.     
  287.     UN_CC["@mozilla.org/embedcomp/window-watcher;1"]
  288.       .getService(UN_CI.nsIWindowWatcher)
  289.       .openWindow(null, "chrome://updatenotifier/content/alert.xul", "alerts", "chrome,dialog=yes,titlebar=no,popup=yes", null);
  290.   },
  291.   
  292.   /**
  293.    * nsIRDFObserver
  294.    */
  295.    onAssert: function(aDataSource, aSource, aProperty, aTarget)
  296.    {
  297.      var pv = aProperty.QueryInterface(UN_CI.nsIRDFResource).Value;
  298.      
  299. //     UN_CS.logStringMessage("onAssert - " + pv);
  300.    },
  301.   
  302.   onUnassert: function(aDataSource, aSource, aProperty, aTarget)
  303.   {
  304.     var pv = aProperty.QueryInterface(UN_CI.nsIRDFResource).Value;
  305.     var opType = null;
  306.     
  307. //    UN_CS.logStringMessage("onUnassert - " + pv);
  308.     
  309.     if (pv.indexOf("#opType") > -1)
  310.     {
  311.       opType = aTarget.QueryInterface(UN_CI.nsIRDFLiteral).Value;
  312.       
  313. //      UN_CS.logStringMessage("opType - " + opType);
  314.       
  315.       this._itemUpdateAction(aDataSource, aSource, UN_ACTION_UPDATE, opType);
  316.     }
  317.     else if (pv.indexOf("#installLocation") > -1)
  318.       this._itemUpdateAction(aDataSource, aSource, UN_ACTION_REMOVE);
  319.   },
  320.   
  321.   onChange: function(aDataSource, aSource, aProperty, aOldTarget, aNewTarget)
  322.   {
  323.     var pv = aProperty.QueryInterface(UN_CI.nsIRDFResource).Value;
  324.     var action = null;
  325.     var opType = null;
  326.     
  327. //    UN_CS.logStringMessage("onChange - " + pv);
  328.     
  329.     if (pv.indexOf("#opType") > -1)
  330.     {
  331.       opType = aNewTarget.QueryInterface(UN_CI.nsIRDFLiteral).Value;
  332.       
  333. //      UN_CS.logStringMessage("opType - " + opType);
  334.       
  335.       if (opType == "none" || opType == "")
  336.         action = UN_ACTION_UPDATE;
  337.       else if (opType == "needs-uninstall" || opType == "needs-disable")
  338.         action = UN_ACTION_REMOVE;
  339.       else if (opType == "needs-install" || opType == "needs-upgrade")
  340.         action = UN_ACTION_INSTALL;
  341.     }
  342.     else if (pv.indexOf("#availableUpdateURL") > -1)
  343.       action = UN_ACTION_UPDATE;
  344.     
  345.     if (action != null)
  346.       this._itemUpdateAction(aDataSource, aSource, action, opType);
  347.   },
  348.   
  349.   onBeginUpdateBatch: function(aDataSource)
  350.   {
  351.     // Not implemented
  352.   },
  353.   
  354.   onEndUpdateBatch: function(aDataSource)
  355.   {
  356.     // Not implemented
  357.   },
  358.   
  359.   onMove: function(aDataSource, aOldSource, aNewSource, aProperty, aTarget)
  360.   {
  361.     // Not implemented
  362.   },
  363.   
  364.   /**
  365.    * nsIAddonUpdateCheckListener
  366.    */
  367.   onUpdateStarted: function()
  368.   {
  369.     this._setBusyStatus(UN_NOTIFY_TYPE_BUSY_CHECKING);
  370.   },
  371.   
  372.   onUpdateEnded: function()
  373.   {
  374.     this._setBusyStatus(UN_NOTIFY_TYPE_BUSY_NONE);
  375.     
  376.     if (this._newUpdate)
  377.       this._showAlert();
  378.   },
  379.   
  380.   onAddonUpdateEnded: function(aAddon, aStatus)
  381.   {
  382.     // Not implemented
  383.   },
  384.   
  385.   onAddonUpdateStarted: function(aAddon)
  386.   {
  387.     // Not implemented
  388.   },
  389.   
  390.   /**
  391.    * nsIAddonUpdateListener
  392.    */
  393.   onStateChange: function (aAddon, aState, aValue)
  394.   {
  395.     switch (aState)
  396.     {
  397.       case UN_CI.nsIXPIProgressDialog.DOWNLOAD_START: {
  398.         this._setBusyStatus(UN_NOTIFY_TYPE_BUSY_DOWNLOAD);
  399.         break;
  400.       }
  401.       case UN_CI.nsIXPIProgressDialog.INSTALL_START: {
  402.         this._setBusyStatus(UN_NOTIFY_TYPE_BUSY_INSTALL);
  403.         break;
  404.       }
  405.       case UN_CI.nsIXPIProgressDialog.DOWNLOAD_DONE:
  406.       case UN_CI.nsIXPIProgressDialog.INSTALL_DONE: {
  407.         this._setBusyStatus(UN_NOTIFY_TYPE_BUSY_NONE);
  408.         break;
  409.       }
  410.       case UN_CI.nsIXPIProgressDialog.DIALOG_CLOSE:
  411.         break;
  412.     }
  413.   },
  414.   
  415.   onProgress: function (aAddon, aValue, aMaxValue)
  416.   {
  417.     // Not implemented
  418.   },
  419.   
  420.   /**
  421.    * nsIAddonInstallListener (Toolkit 1.9, Firefox 3)
  422.    */
  423.   onDownloadStarted: function(aAddon)
  424.   {
  425.     this._setBusyStatus(UN_NOTIFY_TYPE_BUSY_DOWNLOAD);
  426.   },
  427.   
  428.   onDownloadEnded: function(aAddon)
  429.   {
  430.     this._setBusyStatus(UN_NOTIFY_TYPE_BUSY_NONE);
  431.   },
  432.   
  433.   onInstallStarted: function(aAddon)
  434.   {
  435.     this._setBusyStatus(UN_NOTIFY_TYPE_BUSY_INSTALL);
  436.   },
  437.   
  438.   onCompatibilityCheckStarted: function(aAddon)
  439.   {
  440.     // Not implemented
  441.   },
  442.   
  443.   onCompatibilityCheckEnded: function(aAddon, aStatus)
  444.   {
  445.     // Not implemented
  446.   },
  447.   
  448.   onInstallEnded: function(aAddon, aStatus)
  449.   {
  450.     this._setBusyStatus(UN_NOTIFY_TYPE_BUSY_NONE);
  451.   },
  452.   
  453.   onInstallsCompleted: function()
  454.   {
  455.     // Not implemented
  456.   },
  457.   
  458.   onDownloadProgress: function (aAddon, aValue, aMaxValue)
  459.   {
  460.     // Not implemented
  461.   },
  462.   
  463.   QueryInterface: function(iid)
  464.   {
  465.     if (iid.equals(unIManager) ||
  466.         iid.equals(nsIAddonUpdateCheckListener) ||
  467.         iid.equals(nsIAddonUpdateListener) ||
  468.         iid.equals(nsIAddonInstallListener) ||
  469.         iid.equals(nsIObserver) ||
  470.         iid.equals(nsISupports))
  471.       return this;
  472.     throw Components.results.NS_ERROR_NO_INTERFACE;
  473.   }
  474. }
  475.  
  476. function unItem() {}
  477. unItem.prototype = {
  478.   _id: null,
  479.   _name: null,
  480.   _type: null,
  481.   _oldVersion: null,
  482.   _newVersion: null,
  483.   _opType: null,
  484.   _needsRestart: false,
  485.   
  486.   get id() { return this._id; },
  487.   get name() { return this._name; },
  488.   get type() { return this._type; },
  489.   get oldVersion() { return this._oldVersion; },
  490.   get newVersion() { return this._newVersion; },
  491.   get opType() { return this._opType; },
  492.   get needsRestart() { return this._needsRestart; },
  493.   
  494.   set id(aId) { this._id = aId; },
  495.   set name(aName) { this._name = aName; },
  496.   set type(aType) { this._type = aType; },
  497.   set oldVersion(aVersion) { this._oldVersion = aVersion; },
  498.   set newVersion(aVersion) { this._newVersion = aVersion; },
  499.   set opType(aOpType) { this._opType = aOpType; },
  500.   set needsRestart(aNeedsRestart) { this._needsRestart = aNeedsRestart; }
  501. }
  502.  
  503. var myModule = {
  504.   firstTime: true,
  505.   
  506.   myCID: Components.ID("{0090c2b0-9e45-11da-a746-0800200c9a66}"),
  507.   myDesc: "Add-ons Update Manager",
  508.   myProgID: "@longfocus.com/updatenotifier/manager;1",
  509.   myFactory: {
  510.     createInstance: function (outer, iid) {
  511.       if (outer != null)
  512.         throw Components.results.NS_ERROR_NO_AGGREGATION;
  513.       
  514.       return (new unManager()).QueryInterface(iid);
  515.     }
  516.   },
  517.  
  518.   registerSelf: function (compMgr, fileSpec, location, type)
  519.   {
  520.     if (this.firstTime) {
  521.       this.firstTime = false;
  522.       throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
  523.     }
  524.     
  525.     compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  526.     compMgr.registerFactoryLocation(this.myCID, this.myDesc, this.myProgID, fileSpec, location, type);
  527.   },
  528.  
  529.   getClassObject: function (compMgr, cid, iid)
  530.   {
  531.     if (!cid.equals(this.myCID))
  532.       throw Components.results.NS_ERROR_NO_INTERFACE;
  533.     
  534.     if (!iid.equals(Components.interfaces.nsIFactory))
  535.       throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  536.     
  537.     return this.myFactory;
  538.   },
  539.   
  540.   canUnload: function(compMgr) { return true; }
  541. };
  542.  
  543. function NSGetModule(compMgr, fileSpec) { return myModule; }